package org.i0o.webplus.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.i0o.webplus.model.IDomainObject;
import org.i0o.webplus.support.Page;

/**
 * 针对单个DomainObject对象的操作定义. 不依赖于具体ORM实现方案.
 * 
 * @author <a href="mailto:781131@gmail.com">HTF</a>
 */
public interface IDomainObjectDao<D extends IDomainObject>
		extends IDao {

	/**
	 * 根据属性名和属性值查询对象.
	 * 
	 * @param name 查询条件的属性名
	 * @param value 查询条件
	 * @return 符合条件的对象列表
	 */
	List<D> findBy(String name, Object value);

	/**
	 * 根据属性名集合和属性集合查询对象
	 * 
	 * @param names 查询条件的属性名集合
	 * @param values 查询条件集合
	 * @return 符合条件的对象列表
	 */
	List<D> findBy(String[] names, Object[] values);

	/**
	 * 根据集合条件查询对象
	 * 
	 * @param param 条件集合
	 * @return 符合条件的对象列表
	 */
	List<D> findBy(Map<String, Object> param);

	/**
	 * 根据属性名和属性值以Like AnyWhere方式查询对象.
	 * 
	 * @param name 查询条件的属性名
	 * @param value 查询条件
	 * @return 符合条件的对象列表
	 */
	List<D> findByLike(String name, String value);

	/**
	 * 根据属性名和属性值查询单个对象.
	 * 
	 * @param name 查询条件的属性名
	 * @param value 查询条件
	 * @return 符合条件的对象
	 */
	D findUniqueBy(String name, Object value);

	/**
	 * 根据ID获取对象.
	 * 
	 * @param id 指定的ID
	 * @return 符合条件的对象
	 */
	D findById(Serializable id);

	/**
	 * 获取全部对象.
	 * 
	 * @return 对象列表
	 */
	List<D> findAll();

	/**
	 * 判断对象某些属性的值在数据库中不存在重复.
	 * 
	 * @param domainObject 指定的对象
	 * @param names 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
	 * @return 包含重复的内容返回true，否则返回false
	 */
	boolean isNotUnique(D domainObject, String names);

	/**
	 * 删除指定的实体对象.
	 * 
	 * @param o 指定的对象
	 */
	void doDelete(D o);

	/**
	 * 根据ID移除对象.
	 * 
	 * @param id 指定的ID
	 */
	void doDeleteById(Serializable id);

	/**
	 * 根据多个id批量删除对象
	 * 
	 * @param ids 指定的多个ID
	 */
	void doDeleteByIds(Serializable[] ids);

	/**
	 * 保存对象.
	 * 
	 * @param o 指定的对象
	 */
	void doSave(D o);

	/**
	 * 保存一系列对象.
	 * 
	 * @param list 指定的对象list
	 */
	void doSaveAll(Collection<D> list);

	/**
	 * 保存或更新一系列对象.
	 * 
	 * @param list 指定的对象list
	 */
	void doSaveOrUpdateAll(Collection<D> list);

	/**
	 * 更新对象
	 * 
	 * @param o 指定对象
	 */
	void doUpdate(D o);

	/**
	 * 更新一系列对象
	 * 
	 * @param list 指定对象list
	 */
	void doUpdateAll(Collection<D> list);

	/**
	 * 添加或修改对象
	 * 
	 * @param o 指定对象
	 */
	void doSaveOrUpdate(D o);

	/**
	 * 加载指定标识的对象,仅为该对象的代理
	 * 
	 * @param id 对象的id
	 * @return
	 */
	D loadById(Serializable id);

	/**
	 * 根据页码hql分页查询，占位符
	 * 
	 * @param hql hql语句
	 * @param start 起始索引
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedQueryByPageNo(String hql, int start, int pageSize, Object[] parameters);

	/**
	 * hql分页查询，支持匿名参数
	 * 
	 * @param hql hql语句
	 * @param start 起始索引
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedQueryByPageNo(String hql, int start, int pageSize, Map<String, Object> parameter);

	/**
	 * 根据起始索引hql分页查询，占位符
	 * 
	 * @param hql hql语句
	 * @param start 起始索引
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedQueryByStart(String hql, int start, int pageSize, Object[] parameters);

	/**
	 * 根据起始索引hql分页查询，支持匿名参数
	 * 
	 * @param hql hql语句
	 * @param start 起始索引
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedQueryByStart(String hql, int start, int pageSize, Map<String, Object> parameter);

	/**
	 * sql 分页查询，支持SQL语句命名参数的查询
	 * 
	 * @param sql sql字符串
	 * @param start 起始索引
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedSqlQueryByPageNo(String sql, int start, int pageSize, Object[] parameters);

	/**
	 * sql 分页查询，支持SQL语句命名参数的查询
	 * 
	 * @param sql sql字符串
	 * @param start 起始索引
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedSqlQueryByPageNo(String sql, int start, int pageSize, Map<String, Object> parameters);

	/**
	 * 根据起始索引 根据起始索引sql 分页查询，支持SQL语句命名参数的查询
	 * 
	 * @param sql sql字符串
	 * @param start 页码
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedSqlQueryByStart(String sql, int start, int pageSize, Object[] parameters);

	/**
	 * 根据起始索引 sql 分页查询，支持SQL语句命名参数的查询
	 * 
	 * @param sql sql字符串
	 * @param start 页码
	 * @param pageSize 页大小
	 * @param parameter 参数集合
	 * @return Page对象
	 */
	Page pagedSqlQueryByStart(String sql, int start, int pageSize, Map<String, Object> parameters);

	/**
	 * 获取记录总数
	 * 
	 * @return 记录总数
	 */
	Long getCount();
}
